package wangjg.security.interceptor.servlet;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import wangjg.security.SecurityContext;
import wangjg.security.core.LoginModule;
import wangjg.security.core.validator.RequestValidator;
import wangjg.security.http.HttpContext;
import wangjg.security.http.HttpRequest;


public class ServletFilter implements Filter {
	private static Log log = LogFactory.getLog(ServletFilter.class);
	private static String url_nopopedom;
	private static String url_login;
	private String encoding = "utf-8";
	private LoginModule loginModule;
	private RequestValidator requestValidator;
	
	public void destroy() {
		log.debug("destroy.");
	}

	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		this.setCharacterEncoding(request, response);
		//请求路径
		try{
			HttpContext.setRequest(request);
			HttpContext.setResponse(response);
			String servletPath = RequestUtils.getServletPath(request);
			Object user = loginModule.login();
			
			HttpRequest httpRequest = new HttpRequest(servletPath);
			boolean b = this.requestValidator.validate(httpRequest, user);
			if(b){
				chain.doFilter(req, res);
			}else{
				if(url_login.equals(servletPath)||url_nopopedom.equals(servletPath)){
					chain.doFilter(req, res);
					return;
				}
				log.warn("no popedom:"+servletPath);
				if(user==null){
					response.sendRedirect(getFullUrl(request,url_login));
				}else{
					response.sendRedirect(getFullUrl(request,url_nopopedom));
				}
			}
		} finally {
			HttpContext.setRequest(null);
			HttpContext.setResponse(null);
		}
	}
	
	static String getFullUrl(HttpServletRequest request,String url){
		String fullurl = request.getContextPath()+url;
		String re_url;
		String qs = request.getQueryString();
		if(qs!=null){
			re_url=request.getRequestURL().toString()+"?"+qs;
		}else{
			re_url=request.getRequestURL().toString();
		}
		try {
			fullurl+="?redirect_url="+URLEncoder.encode(re_url,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return fullurl;
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		url_nopopedom = filterConfig.getInitParameter("url_nopopedom");
		url_login = filterConfig.getInitParameter("url_login");
		encoding = filterConfig.getInitParameter("encoding");
		String config = filterConfig.getInitParameter("config");
		SecurityContext sc = SecurityContext.load(config);
		this.requestValidator = sc.getRequestValidator();
		this.loginModule = sc.getLoginModule();
	}

	private void setCharacterEncoding(ServletRequest request,ServletResponse response){
		if(request.getCharacterEncoding() == null) {
			if(encoding != null) {
				try {
					request.setCharacterEncoding(encoding);
					response.setCharacterEncoding(encoding);
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

/*
 web.xml配置说明
	<!-- security filter  -->
	<filter>
		<filter-name>SecurityFilter</filter-name>
		<filter-class>com.online.security.http.ServletFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
		<init-param>
			<param-name>url_nopopedom</param-name>
			<param-value>/common/nopopedom.jsp</param-value>
		</init-param>
		<init-param>
			<param-name>url_login</param-name>
			<param-value>/user/guest/login.jsp</param-value>
		</init-param>
		<init-param>
			<param-name>config</param-name>
			<param-value>/security.xml</param-value>
		</init-param>
	</filter>
	
	<filter-mapping>
		<filter-name>SecurityFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
 */
